import time


def runTime(func):  # 装饰器，传入一个参数，把我们要运行的函数 countPrintNum() 作为参数传入
    def wrapper(*args):  # 表示的是，要运行这个函数，需要运行哪些内容,*args是接收函数countPrintNum中的不定长参数
        time1 = time.time()  # 运行这个函数前，截取一个时间
        result = func(*args)  # 然后运行我们的函数（func(*args)等价于countPrintNum(maxNum)，把记录个数的 countNum 记录并保存起来
        time2 = time.time()  # 运行结束，再获取一个当前时间
        print("Total time: {:.4} s".format(time2 - time1))  # 然后，打印总耗时,保留4位小数
        return result  # 最后，返回记录个数的 countNum

    return wrapper



'''
@runTime，相当于countPrintNum = runTime(countPrintNum)  + countPrintNum()
'''
@runTime
def countPrintNum(maxNum):  # 如果想要统计到任意数之间的质数，附带参数时,我们需要把这个参数 maxNum 带到装饰器中
    countNum = 0
    for i in range(2, maxNum):
        if isPrime(i):
            countNum += 1
            # print(i)
    return countNum


def isPrime(num):
    if num < 2:
        return False
    elif num == 2:
        return True
    else:
        for i in range(2, num):
            if num % i == 0:
                return False
        return True


if __name__ == "__main__":
    countNum = countPrintNum(10)  # 这里可以传入大于2的任意数
    print(countNum)
'''
当运行最后的 countPrintNum() 函数时，调用过程是这样的：
    先执行 countPrintNum = runTime(countPrintNum)，此时的变量 countPrintNum 指向的是 runTime()
    runTime(func)中传参的是 countPrintNum，返回的 wrapper，而 wrapper 又会调用到原函数 countPrintNum
所以，先执行 wrapper 函数里面的函数，然后再执行 countPrintNum()函数里的。
'''